import jwt
import json
import datetime
import logging
import threading
from ccframe import Router, Application, Filter
from ccframe.utils import jsonfy
from webob import Response
from functools import wraps
from webob.exc import HTTPUnauthorized

__KEY = 'xxxyyyyzzzzz'
logging.basicConfig(level=logging.INFO)


class AccessLogFilter(Filter):
    def __init__(self):
        self.local = threading.local()
        self.local.start = None
        self.local.request = None

    def before_request(self, ctx, request):
        self.local.start = datetime.datetime.now()
        self.local.request = request
        return request

    def after_request(self, ctx, response):
        now = datetime.datetime.now()
        time = (now - self.local.start).total_seconds()
        logging.info(str(time))
        return response


router = Router(filters=[AccessLogFilter()])


def authenticated(fn):
    @wraps(fn)
    def wrap(ctx, request):
        token = request.headers.get('X-Authorization-Token')
        if token is None:
            raise HTTPUnauthorized()
        try:
            decoded = jwt.decode(token, __KEY, ['HS512'])
            user = decoded.get('user')
            if user is None:
                raise HTTPUnauthorized()
            request.user = user
            return fn(ctx, request)
        except Exception:
            raise HTTPUnauthorized()
    return wrap


@router.route('/')
@authenticated
def main(ctx, request):
    return Response('hello world')


@router.route('/login', methods=['POST'])
def login(ctx, request):
    payload = json.loads(request.body.decode())
    if payload.get('username') == 'lavenliu' and \
       payload.get('password') == 'pass':
        exp = datetime.datetime.utcnow() + datetime.timedelta(hours=8)
        token = jwt.encode({'user': 'lavenliu',
                            'exp': exp},
                           __KEY,
                           'HS512').decode()
        # return Response(json.dumps({'token': token}),
        #                 content_type='application/json')
        return jsonfy(code=200, token=token)
    # return Response(json.dumps(
    #     {'code': 401, 'message': 'username or password not matched'}),
    #                 content_type='application/json')
    return jsonfy(code=401, message='username or password not matched')


app = Application([router])

if __name__ == "__main__":
    from wsgiref.simple_server import make_server

    server = make_server('0.0.0.0', 3001, app)
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        server.shutdown()
